import { computed, ref, shallowRef } from 'vue'
import { defineStore } from 'pinia'
import { $t } from '@/i18n'
import { POPUP_DIALOG_TYPE } from '@/constant'

const popupConfigList = []
const dataList = []
let currIndex = -1

export const usePopupDialogStore = defineStore('popupDialog', () => {
  const type = ref(null)
  const image = ref(null)
  const title = ref(null)
  const subtitle = ref(null)
  const content = ref(null)
  const fromCenter = ref(null)
  const actions = ref(null)
  const texts = ref(null)
  const cancelLightTheme = ref(false)
  const showClose = ref(true)
  const showConfirm = ref(true)

  const backCallback = ref(null)
  const showBack = computed(() => !!backCallback.value)

  const buttonSlot = shallowRef(null)
  const remarkSlot = shallowRef(null)

  const confirmData = ref(null)
  const confirmDisabled = ref(false)
  const confirmGradient = ref(false)
  const closeCallback = ref(null)

  const isOpen = computed(() => type.value !== null)
  const isSelection = computed(() => type.value === POPUP_DIALOG_TYPE.SELECTION)
  const isPremium = computed(() => [POPUP_DIALOG_TYPE.PREMIUM, POPUP_DIALOG_TYPE.PREMIUM_SUCCESS].includes(type.value))

  function $popupDialog(popupType, options) {
    addConfig({
      type: popupType,
      ...options,
    })
    return { next: $popupDialog, open: openNext }
  }

  function $alert(options) {
    if (options.cancel) {
      throw new Error('$alert cannot set cancel callback, use $confirm instead.')
    }
    addConfig({
      type: POPUP_DIALOG_TYPE.ALERT,
      ...options,
    })
    return { next: $popupDialog, open: openNext }
  }

  function $confirm(options) {
    console.log('options', options)
    addConfig({
      type: POPUP_DIALOG_TYPE.CONFIRM,
      ...options,
    })
    return { next: $popupDialog, open: openNext }
  }

  function $selection(selections, options) {
    if (!Array.isArray(selections)) {
      throw new Error(`$selection options must be Array`)
    }
    addConfig({
      type: POPUP_DIALOG_TYPE.SELECTION,
      ...options,
      content: selections,
    })
    return { next: selectionPopupDialog, open: openNext }
  }

  function selectionPopupDialog(optionsArray) {
    if (!Array.isArray(optionsArray)) {
      throw new Error('Options after $selection must be Array')
    }
    addConfigArray(optionsArray)
    return { next: $popupDialog, open: openNext }
  }

  function openNext(data) {
    currIndex += 1
    const config = popupConfigList[currIndex]
    if (config) {
      if (Array.isArray(config)) {
        if (config[data]) {
          setRefs(config[data])
          return true
        }
      } else {
        setRefs(config)
        return true
      }
    }
    return false
  }

  function close() {
    type.value = null
    image.value = null
    title.value = null
    content.value = null
    fromCenter.value = null
    actions.value = null
    texts.value = null
    confirmData.value = null
    closeCallback.value = null
    backCallback.value = null
    buttonSlot.value = null
    remarkSlot.value = null

    popupConfigList.length = 0
    dataList.length = 0
    currIndex = -1
  }

  function setInputData(data) {
    dataList[currIndex] = data
  }

  function getPrevInputData() {
    return dataList[currIndex - 1]
  }

  function setConfirmData(action) {
    confirmData.value = action
  }

  function addConfig({
    type,
    image,
    title,
    subtitle,
    content,
    fromCenter,
    confirm,
    cancel,
    confirmText = $t('common.confirm'),
    cancelText = $t('common.cancel'),
    cancelLightTheme = false,
    confirmGradient = false,
    showClose = true,
    showConfirm = true,
    buttonSlot = null,
    remarkSlot = null,
  }) {
    popupConfigList.push({
      type,
      image,
      title,
      subtitle,
      content,
      fromCenter,
      confirm,
      cancel,
      confirmText,
      cancelText,
      cancelLightTheme,
      confirmGradient,
      showClose,
      showConfirm,
      buttonSlot,
      remarkSlot,
    })
  }

  function addConfigArray(configArray) {
    popupConfigList.push(
      configArray.map((c) => {
        if (!c.confirmText) {
          c.confirmText = $t('common.confirm')
        }
        if (!c.cancelText) {
          c.cancelText = $t('common.cancel')
        }
        return c
      }),
    )
  }

  function setRefs({
    type: typeOpt = null,
    image: imageOpt = null,
    title: titleOpt = null,
    subtitle: subtitleOpt = null,
    content: contentOpt = null,
    fromCenter: fromCenterOpt = null,
    confirm,
    cancel,
    confirmText,
    cancelText,
    cancelLightTheme: cancelLightThemeOpt = false,
    confirmGradient: confirmGradientOpt = false,
    showClose: showCloseOpt = true,
    showConfirm: showConfirmOpt = true,
    buttonSlot: buttonSlotOpt = null,
    remarkSlot: remarkSlotOpt = null,
  }) {
    if (!typeOpt && typeOpt !== 0) {
      console.warn(`popup dialog type unexpected value of ${typeOpt}`)
    }
    type.value = typeOpt
    image.value = imageOpt
    title.value = titleOpt
    subtitle.value = subtitleOpt
    content.value = contentOpt
    fromCenter.value = fromCenterOpt
    actions.value = { confirm, cancel }
    texts.value = { confirm: confirmText, cancel: cancelText }
    cancelLightTheme.value = cancelLightThemeOpt
    confirmGradient.value = confirmGradientOpt
    showClose.value = showCloseOpt
    showConfirm.value = showConfirmOpt
    buttonSlot.value = buttonSlotOpt
    remarkSlot.value = remarkSlotOpt
  }

  return {
    type,
    image,
    title,
    subtitle,
    content,
    fromCenter,
    actions,
    texts,
    confirmData,
    confirmDisabled,
    closeCallback,

    isOpen,
    isSelection,
    isPremium,

    cancelLightTheme,
    confirmGradient,
    showClose,
    showConfirm,
    showBack,
    backCallback,
    buttonSlot,
    remarkSlot,
    $popupDialog,
    $alert,
    $confirm,
    $selection,
    openNext,
    close,
    setInputData,
    getPrevInputData,
    setConfirmData,
  }
})
